
using System;
using System.Collections.Generic;

namespace EventUtils
{
    /// <summary>
    /// 事件中心
    /// </summary>
    public class EventCenter
    {
        //存放各种事件的字典
        private static Dictionary<EventType, Delegate> m_EventTable = new Dictionary<EventType, Delegate>();

        //精简代码
        #region 精简
        private static void OnListenerAdding(EventType eventType, Delegate callback)
        {
            if (!m_EventTable.ContainsKey(eventType))
            {
                m_EventTable.Add(eventType, null);
            }
            Delegate del = m_EventTable[eventType];
            //判断该事件码对应的事件类型（参数）是否一样
            if (del != null && del.GetType() != callback.GetType())
            {
                throw new Exception(string.Format("尝试添加事件失败"));
            }
        }

        private static void OnListenerRemoving(EventType eventType, Delegate callback)
        {
            if (m_EventTable.ContainsKey(eventType))
            {
                Delegate del = m_EventTable[eventType];
                if (del == null)
                {
                    throw new Exception(string.Format("移除失败，对应事件为空"));
                }
                else if (del.GetType() != callback.GetType())
                {
                    throw new Exception(string.Format("移除失败，对应事件不同"));
                }
            }
            else
            {
                throw new Exception(string.Format("移除失败，事件码为空"));
            }
        }

        private static void OnListenerRemoved(EventType eventType)
        {
            if (m_EventTable[eventType] == null)
            {
                m_EventTable.Remove(eventType);
            }
        }

        #endregion

        #region NoParamter
        //添加事件
        public static void AddListener(EventType eventType, CallBack callback)
        {
            OnListenerAdding(eventType, callback);
            m_EventTable[eventType] = (CallBack)m_EventTable[eventType] + callback;
        }

        //移除事件
        public static void RemoveListener(EventType eventType, CallBack callback)
        {
            OnListenerRemoving(eventType, callback);
            m_EventTable[eventType] = (CallBack)m_EventTable[eventType] - callback;
            OnListenerRemoved(eventType);
        }

        //事件的广播
        public static void BroadCast(EventType eventType)
        {
            Delegate del;
            if (m_EventTable.TryGetValue(eventType, out del))
            {
                CallBack callback = del as CallBack;
                if (callback != null)
                {
                    callback();
                }
                else
                {
                    throw new Exception(string.Format("广播事件错误，对应事件为空"));
                }
            }

        }
        #endregion

        #region One Paramter

        //添加事件
        public static void AddListener<T>(EventType eventType, CallBack<T> callback)
        {
            OnListenerAdding(eventType, callback);
            m_EventTable[eventType] = (CallBack<T>)m_EventTable[eventType] + callback;
        }

        //移除事件
        public static void RemoveListener<T>(EventType eventType, CallBack<T> callback)
        {
            OnListenerRemoving(eventType, callback);
            m_EventTable[eventType] = (CallBack<T>)m_EventTable[eventType] - callback;
            OnListenerRemoved(eventType);

        }

        //事件的广播
        public static void BroadCast<T>(EventType eventType, T arg)
        {
            Delegate del;
            if (m_EventTable.TryGetValue(eventType, out del))
            {
                CallBack<T> callback = del as CallBack<T>;
                if (callback != null)
                {
                    callback(arg);
                }
                else
                {
                    throw new Exception(string.Format("广播事件错误，对应事件为空"));
                }
            }

        }
        #endregion

        #region Two Paramters
        //添加事件
        public static void AddListener<T, X>(EventType eventType, CallBack<T, X> callback)
        {
            OnListenerAdding(eventType, callback);
            m_EventTable[eventType] = (CallBack<T, X>)m_EventTable[eventType] + callback;
        }

        //移除事件
        public static void RemoveListener<T, X>(EventType eventType, CallBack<T, X> callback)
        {
            OnListenerRemoving(eventType, callback);
            m_EventTable[eventType] = (CallBack<T, X>)m_EventTable[eventType] - callback;
            OnListenerRemoved(eventType);

        }

        //事件的广播
        public static void BroadCast<T, X>(EventType eventType, T arg1, X arg2)
        {
            Delegate del;
            if (m_EventTable.TryGetValue(eventType, out del))
            {
                CallBack<T, X> callback = del as CallBack<T, X>;
                if (callback != null)
                {
                    callback(arg1, arg2);
                }
                else
                {
                    throw new Exception(string.Format("广播事件错误，对应事件为空"));
                }
            }

        }
        #endregion
        
        #region three Paramters
        //添加事件
        public static void AddListener<T, X, Z>(EventType eventType, CallBack<T, X, Z> callback)
        {
            OnListenerAdding(eventType, callback);
            m_EventTable[eventType] = (CallBack<T, X, Z>)m_EventTable[eventType] + callback;
        }

        //移除事件
        public static void RemoveListener<T, X, Z>(EventType eventType, CallBack<T, X, Z> callback)
        {
            OnListenerRemoving(eventType, callback);
            m_EventTable[eventType] = (CallBack<T, X, Z>)m_EventTable[eventType] - callback;
            OnListenerRemoved(eventType);

        }

        //事件的广播
        public static void BroadCast<T, X, Z>(EventType eventType, T arg1, X arg2, Z arg3)
        {
            Delegate del;
            if (m_EventTable.TryGetValue(eventType, out del))
            {
                CallBack<T, X, Z> callback = del as CallBack<T, X, Z>;
                if (callback != null)
                {
                    callback(arg1, arg2, arg3);
                }
                else
                {
                    throw new Exception(string.Format("广播事件错误，对应事件为空"));
                }
            }

        }
        #endregion
    }

}
